package com.zygh.lz.service.impl;

import cn.hutool.http.HttpRequest;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.zygh.lz.controller.FileUpload;
import com.zygh.lz.dao.SectionMapper;
import com.zygh.lz.dao.app.*;
import com.zygh.lz.entity.Section;
import com.zygh.lz.entity.Staff;
import com.zygh.lz.entity.app.*;
import com.zygh.lz.entity.vo.AppTrailerInfoVO;
import com.zygh.lz.entity.vo.AppTrailerVO;
import com.zygh.lz.service.StaffService;
import com.zygh.lz.stapprove.ResultUtil;
import com.zygh.lz.vo.ResultBean;
import com.zygh.lz.vo.ResultBeans;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

@Slf4j
@Service
public class AppTrailerInfoService extends ServiceImpl<AppTrailerInfoMapper, AppTrailerInfo> {

    @Resource
    private AppTrailerInfoMapper appTrailerInfoMapper;
    @Resource
    private AppPictureMapper appPictureMapper;
    @Resource
    private AppPlateMapper appPlateMapper;
    @Resource
    private AppParkMapper appParkMapper;

    @Resource
    private AppNoteMapper appNoteMapper;
    @Resource
    private AppTrafficMapper appTrafficMapper;
    @Resource
    private StaffService staffService;
    @Resource
    private SectionMapper sectionMapper;

    @Resource
    private AppTrailerAbnormalCauseService appTrailerAbnormalCauseService;
    @Resource
    private AppImageHashService appImageHashService;

    @Value("${plate.gateway}")
    private String gateway;

    @Value("${plate.imageIsExist}")
    private String imageIsExistUrl;

    @Value("${plate.identifyTheLicensePlateNo}")
    private String identifyTheLicensePlateNoUrl;
    @Value("${plate.pictureCheck}")
    private String pictureCheck;

    @Value("${trailer.picture-path}")
    private String picturePath;

    //上报拖车信息
    public ResultBeans addTrailerInfo(AppTrailerInfo appTrailerInfo) {
        return ResultUtil.resultBeansSuccess(appTrailerInfoMapper.insert(appTrailerInfo));
    }

    //修改拖车信息
    public ResultBeans updateTrailerInfo(AppTrailerInfo appTrailerInfo) {
        return ResultUtil.resultBeansSuccess(appTrailerInfoMapper.updateById(appTrailerInfo));
    }


    //拖车信息查询
    public ResultBeans findTrailerInfo(String warningSignal, String vehiclePlate, Integer status,
                                       Integer code, String startTime, String endTime, Integer driverState, int current, int size) {
        PageHelper.startPage(current, size);

        List<Map<String, Object>> trailerInfo = appTrailerInfoMapper.findTrailerInfo(warningSignal, vehiclePlate,
                status, code, startTime, endTime, driverState);
        PageInfo<Map<String, Object>> pageInfo = new PageInfo<>(trailerInfo);
        return ResultUtil.resultBeansSuccess(pageInfo);
    }

    //图片上传
    public ResultBeans uploadTrailer(AppPicture appPicture) {
        AppPicture appPicture1 = appPictureMapper.selectOne(Wrappers.<AppPicture>lambdaQuery()
                .eq(AppPicture::getCode, appPicture.getCode())
                .eq(AppPicture::getOrder, appPicture.getOrder()).last("limit 1"));
        if (appPicture1 != null) {
            appImageHashService.remove(Wrappers.<AppImageHash>lambdaQuery()
                    .eq(AppImageHash::getCode, appPicture.getCode())
                    .eq(AppImageHash::getOrder, appPicture.getOrder()));
            appTrailerAbnormalCauseService.remove(Wrappers.<AppTrailerAbnormalCause>lambdaQuery()
                    .eq(AppTrailerAbnormalCause::getCode, appPicture.getCode()));
//            appPicture1.setPicture(appPicture.getPicture());
//            return ResultUtil.resultBeansSuccess(appPictureMapper.updateById(appPicture1));
            appPictureMapper.deleteById(appPicture1.getId());
        }
        return ResultUtil.resultBeansSuccess(appPictureMapper.insert(appPicture));
        //return ResultUtil.resultBeansSuccess(appPictureMapper.insert(appPicture));
    }


    //查询照片是否存在
    public ResultBean findPicture(AppPicture appPicture) {
        //查看图片是否存在，存在覆盖，不存在新增
        AppPicture appPicture1 = appPictureMapper.selectOne(Wrappers.<AppPicture>lambdaQuery()
                .eq(AppPicture::getCode, appPicture.getCode())
                .eq(AppPicture::getOrder, appPicture.getOrder()).last("limit 1"));
        if (appPicture1 != null) {
            appImageHashService.remove(Wrappers.<AppImageHash>lambdaQuery()
                    .eq(AppImageHash::getCode, appPicture.getCode())
                    .eq(AppImageHash::getOrder, appPicture.getOrder()));
            appTrailerAbnormalCauseService.remove(Wrappers.<AppTrailerAbnormalCause>lambdaQuery()
                    .eq(AppTrailerAbnormalCause::getCode, appPicture.getCode()));
//            appPicture1.setPicture(appPicture.getPicture());
//            return ResultUtil.resultBeansSuccess(appPictureMapper.updateById(appPicture1));
            appPictureMapper.deleteById(appPicture1.getId());
        }

        //修改拖车信息状态
        AppTrailerInfo one = appTrailerInfoMapper.selectOne(Wrappers.<AppTrailerInfo>lambdaQuery()
                .eq(AppTrailerInfo::getCode, appPicture.getCode()));
        one.setStatus(appPicture.getOrder());
        if (appPicture.getOrder() == 2) {
            one.setDriverState(2);
        }
        appTrailerInfoMapper.updateById(one);

        return ResultUtil.execOp(appPictureMapper.insert(appPicture), "上传");
    }


    public ResultBeans findTrailierInfoById(Integer id) {
        Map<String, Object> appTrailerInfoById = appTrailerInfoMapper.findAppTrailerInfoById(id);
        List<AppPicture> pictureList = appPictureMapper.selectList(Wrappers.<AppPicture>lambdaQuery()
                .eq(AppPicture::getCode, appTrailerInfoById.get("code"))
                .orderByAsc(AppPicture::getOrder));
        List<AppTrailerAbnormalCause> abnormalCauseList = appPictureMapper.findPictureAbnormalCauseByCode((String) appTrailerInfoById.get("code"));
        List<String> collect = abnormalCauseList.stream().map(AppTrailerAbnormalCause::getAbnormalCause).collect(Collectors.toList());
        if (appTrailerInfoById.size() > 0) {
            List<String> images = new ArrayList<>();
            for (AppPicture appPicture : pictureList) {
                try {
                    images.add(FileUpload.ReadPictureByPath(picturePath + appPicture.getPicture()));
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
            appTrailerInfoById.put("picture", JSON.toJSON(images));
            appTrailerInfoById.put("abnormalCauseList", JSON.toJSON(collect));
        }
        return ResultUtil.resultBeansSuccess(appTrailerInfoById);
    }

    //获取车辆类型列表
    public ResultBeans findAppPlateAll() {
        List<AppPlate> appPlates = appPlateMapper.selectList(Wrappers.<AppPlate>lambdaQuery()
                .orderByAsc(AppPlate::getSort));
        return ResultUtil.resultBeansSuccess(appPlates);
    }

    //获取停车场信息列表
    public ResultBeans findAppParkAll(Integer id) {
        return ResultUtil.resultBeansSuccess(appParkMapper.findAppPark(id));
    }

    //新增需发送短信的信息
    public int insertNote(AppNote appNote) {
        AppNote note = appNoteMapper.selectOne(Wrappers.<AppNote>lambdaQuery().eq(AppNote::getCode, appNote.getCode()));
        if (note != null) {
            return appNoteMapper.updateById(appNote);
        }
        return appNoteMapper.insert(appNote);

    }

    public int findAppNoteByCode(String code) {
        return appNoteMapper.selectCount(Wrappers.<AppNote>lambdaQuery().eq(AppNote::getCode, code));
    }


    public List<AppNote> findAppNote() {
        return appNoteMapper.selectList(Wrappers.<AppNote>lambdaQuery()
                .eq(AppNote::getStatus, 0)
                .ne(AppNote::getPhone, "")
                .isNotNull(AppNote::getPhone));
    }

    public int updateAppNote(AppNote appNote) {
        return appNoteMapper.updateById(appNote);
    }


    public List<AppTraffic> findAppTrafficById(Integer id) {
        return appTrafficMapper.selectList(null);
    }

    public List<AppTrailerVO> findNoSync() {
        return appTrafficMapper.findNoSync();
    }


    public String getAddress(String name) {
        AppPark appPark = appParkMapper.selectOne(Wrappers.<AppPark>lambdaQuery()
                .eq(AppPark::getName, name).last("limit 1"));

        return appPark != null ? appPark.getAddress() : "";
    }

    public AppPark getAppPark(Integer parkCode) {
        AppPark appPark = appParkMapper.selectOne(Wrappers.<AppPark>lambdaQuery()
                .eq(AppPark::getCode, parkCode).last("limit 1"));
//        log.info("获取停车场信息：parkCode:{}，停车场信息：{}", parkCode, JSON.toJSONString(appPark));
        return appPark;
    }

    public AppPicture getPicture(String code, Integer order) {
        return appPictureMapper.selectOne(Wrappers.<AppPicture>lambdaQuery()
                .eq(AppPicture::getCode, code).eq(AppPicture::getOrder, order));
    }

    public JSONObject pictureCheck(String base64) {
        Map<String, Object> param = new HashMap<>();
        param.put("base64", base64);
        String result = HttpRequest.post(gateway + pictureCheck)
                .header("Content-Type", "application/json")
                .body(JSON.toJSONString(param))
                .execute().body();
        return JSONObject.parseObject(result).getJSONObject("result");
    }

    public String identifyTheLicensePlateNo(String base64) {
        Map<String, Object> param = new HashMap<>();
        param.put("base64", base64);
        String result = HttpRequest.post(gateway + identifyTheLicensePlateNoUrl)
                .header("Content-Type", "application/json")
                .body(JSON.toJSONString(param))
                .execute().body();
        JSONObject object = JSONObject.parseObject(result);
        if (object.getInteger("code") == 200) {
            return object.getString("result");
        } else if (object.getInteger("code") == 500) {
            return object.getString("message");
        }
        return "无法识别";
    }

    public ResultBeans trailerStats(String policeNumber, Date startTimeOfCurrentMonth, Date endTimeOfCurrentMonth) {
        Staff staff = staffService.getOne(Wrappers.<Staff>lambdaQuery().eq(Staff::getStaffNum, policeNumber));
        // 完成拖车
        Integer successCount = 0;
        // 异常拖车
        Integer abnormalCount = 0;
        // 支队拖车总数量
        Integer departmentCount = 0;
        try {
            successCount = baseMapper.selectCount(Wrappers.<AppTrailerInfo>lambdaQuery()
                    .eq(AppTrailerInfo::getWarningSignal, policeNumber)
                    .between(AppTrailerInfo::getCreatTime, startTimeOfCurrentMonth, endTimeOfCurrentMonth)
                    .eq(AppTrailerInfo::getIsDel, 0)
                    .eq(AppTrailerInfo::getDriverState, 2));
            abnormalCount = baseMapper.selectCount(Wrappers.<AppTrailerInfo>lambdaQuery()
                    .eq(AppTrailerInfo::getWarningSignal, policeNumber)
                    .between(AppTrailerInfo::getCreatTime, startTimeOfCurrentMonth, endTimeOfCurrentMonth)
                    .eq(AppTrailerInfo::getIsDel, 0)
                    .eq(AppTrailerInfo::getDriverState, 4));
            departmentCount = baseMapper.selectCount(Wrappers.<AppTrailerInfo>lambdaQuery()
                    .eq(AppTrailerInfo::getSectionId, staff.getSysSectionId())
                    .between(AppTrailerInfo::getCreatTime, startTimeOfCurrentMonth, endTimeOfCurrentMonth)
                    .eq(AppTrailerInfo::getIsDel, 0)
                    .eq(AppTrailerInfo::getDriverState, 2));
        } catch (Exception e) {
            e.printStackTrace();
        }
        HashMap<String, Integer> hashMap = new HashMap<>();
        hashMap.put("successCount", successCount);
        hashMap.put("abnormalCount", abnormalCount);
        hashMap.put("departmentCount", departmentCount);


        return ResultUtil.resultBeansSuccess(hashMap);
    }

    public ResultBeans trailerInfoStats(String policeNumber) {
        // 待审批
        Integer pendingApprovalCount = 0;
        // 待补充
        Integer waitSupplementCount = 0;
        // 异常待审核
        Integer abnormalCount = 0;
        try {
            pendingApprovalCount = baseMapper.selectCount(Wrappers.<AppTrailerInfo>lambdaQuery()
                    .eq(AppTrailerInfo::getWarningSignal, policeNumber)
                    .eq(AppTrailerInfo::getIsDel, 0)
                    .eq(AppTrailerInfo::getDriverState, 1));
            waitSupplementCount = baseMapper.selectCount(Wrappers.<AppTrailerInfo>lambdaQuery()
                    .eq(AppTrailerInfo::getWarningSignal, policeNumber)
                    .eq(AppTrailerInfo::getIsDel, 0)
                    .eq(AppTrailerInfo::getDriverState, 0));
            abnormalCount = baseMapper.selectCount(Wrappers.<AppTrailerInfo>lambdaQuery()
                    .eq(AppTrailerInfo::getWarningSignal, policeNumber)
                    .eq(AppTrailerInfo::getIsDel, 0)
                    .eq(AppTrailerInfo::getDriverState, 4));
        } catch (Exception e) {
            e.printStackTrace();
        }
        HashMap<String, Integer> hashMap = new HashMap<>();
        hashMap.put("pendingApprovalCount", pendingApprovalCount);
        hashMap.put("waitSupplementCount", waitSupplementCount);
        hashMap.put("abnormalCount", abnormalCount);
        return ResultUtil.resultBeansSuccess(hashMap);
    }

    public ResultBeans parkStats(String policeNumber) {
        // 待审批
        Integer pendingApprovalCount = 0;
        // 已通过
        Integer successCount = 0;
        // 未通过
        Integer failedCount = 0;
        Staff staff = staffService.selectStaffByNum(policeNumber);
        Section section = sectionMapper.selectByPrimaryKey(staff.getSysSectionId());
        try {
            pendingApprovalCount = appParkMapper.selectCount(Wrappers.<AppPark>lambdaQuery()
                    .eq(AppPark::getDeptId, section.getSectionPid())
                    .eq(AppPark::getIsDel, 0)
                    .eq(AppPark::getState, 0));
            successCount = appParkMapper.selectCount(Wrappers.<AppPark>lambdaQuery()
                    .eq(AppPark::getDeptId, section.getSectionPid())
                    .eq(AppPark::getIsDel, 0)
                    .eq(AppPark::getState, 1));
            failedCount = appParkMapper.selectCount(Wrappers.<AppPark>lambdaQuery()
                    .eq(AppPark::getDeptId, section.getSectionPid())
                    .eq(AppPark::getIsDel, 0)
                    .eq(AppPark::getState, 2));
        } catch (Exception e) {
            e.printStackTrace();
        }
        HashMap<String, Integer> hashMap = new HashMap<>();
        hashMap.put("pendingApprovalCount", pendingApprovalCount);
        hashMap.put("successCount", successCount);
        hashMap.put("failedCount", failedCount);
        return ResultUtil.resultBeansSuccess(hashMap);
    }

    public List<AppTrailerInfoVO> findTrailerByBoard() {
        List<AppTrailerInfoVO> trailerByBoard = appTrailerInfoMapper.findTrailerByBoard();
        List<String> codeList = trailerByBoard.stream().map(AppTrailerInfoVO::getCode).collect(Collectors.toList());
        for (AppTrailerInfoVO trailerInfoVO : trailerByBoard) {
            AppPicture picture = appPictureMapper.selectOne(Wrappers.<AppPicture>lambdaQuery()
                    .eq(AppPicture::getCode, trailerInfoVO.getCode())
                    .eq(AppPicture::getOrder, 2).last("Limit 1"));
            if (picture != null) {
                String imageBase64 = null;
                try {
                    imageBase64 = FileUpload.ReadPictureByPath(picturePath + picture.getPicture());
                } catch (Exception e) {
                    log.error(e.getMessage(), e);
                }
                picture.setPicture(imageBase64);
            }
            trailerInfoVO.setTrailerPicture(picture);
        }
        updateTrailerByBoard(codeList);
        return trailerByBoard;
    }

    @Async
    public void updateTrailerByBoard(List<String> codeList) {
        if (!codeList.isEmpty()) {
            appTrailerInfoMapper.updateSignBoard(codeList);
        }
    }
}
